package com.ThreadImp;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

//使用Callable接口 FutureTask对象  实现售票功能 (加锁)
//对象锁
public class SellTicket {
    public static void main(String[] args) {
        Ticket ticket = new Ticket(1050);
        TicketService ts = new TicketService(ticket);
        //3个线程 同一个资源
        for (int i = 1; i < 4; i++) {
            FutureTask<Boolean> ft = new FutureTask<Boolean>(ts);
            Thread t = new Thread(ft,"ticketService"+i);
            t.start();
        }
        //此时有5个窗口  true:输出只有一个窗口
            //使用 FutureTask对象作为Thread的对象的target 创建并启动新线程; 返回值类型Void

//            try{
//                boolean fg = ft.get();
//                System.out.println(fg);
//            } catch (InterruptedException | ExecutionException e) {
//                e.printStackTrace();
//            }

//        }

//        FutureTask<Void> ft = new FutureTask<Void>(ts);
//        new Thread(ft,"ticketService0").start();
//        new Thread(ft,"ticketService2").start();
    }
}

//业务
class TicketService implements Callable<Boolean>{
    //调用Ticket类
    private Ticket ticket;
    boolean flag = true;
    public TicketService(Ticket ticket) {
        this.ticket = ticket;
    }

    @Override
    public Boolean call(){
        while (flag){
            //锁住代码块 只允许当前线程使用该对象
            Buy(ticket);
            try{
                Thread.sleep(10); //不会释放锁
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    private void Buy(Ticket ticket){
        synchronized (ticket){
            int currentNo = ticket.getTicketNum();
            if(currentNo>0){
//                    System.out.println(Thread.currentThread().getName() + "准备出票,剩余票数:" + currentNo + "张");
                --currentNo;
                //重设票数
                ticket.setTicketNum(currentNo);
                try{
                    Thread.sleep(10); //不会释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "卖出一张,剩余票数:" + currentNo + "张");

            }else{
                System.out.println(Thread.currentThread().getName() + "余票不足,停止售票!");
                flag = false;
            }
        }
    }

}

//实体
class Ticket{
    private int ticketNum;
    public Ticket(int n) {
        this.ticketNum = n;
    }

    public int getTicketNum() {
        return ticketNum;
    }

    public void setTicketNum(int n) {
        this.ticketNum = n;
    }
}
